package py.com.alfa.escriba.web.services.impl;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import py.com.alfa.escriba.exception.ErrorCode;
import py.com.alfa.escriba.exception.ServiceException;
import py.com.alfa.escriba.persistence.dao.AdminDAO;
import py.com.alfa.escriba.persistence.dao.ComparecientesDAO;
import py.com.alfa.escriba.persistence.dao.EscribanosDAO;
import py.com.alfa.escriba.persistence.dao.PaisDAO;
import py.com.alfa.escriba.persistence.dao.PersonasDAO;
import py.com.alfa.escriba.persistence.dao.PersonasdocumentosDAO;
import py.com.alfa.escriba.persistence.dao.PersonasjuridicasinfoDAO;
import py.com.alfa.escriba.persistence.dao.PoderesDAO;
import py.com.alfa.escriba.persistence.dao.ReferenciaDAO;
import py.com.alfa.escriba.persistence.dto.ComparecientesDTO;
import py.com.alfa.escriba.persistence.dto.EscribanosDTO;
import py.com.alfa.escriba.persistence.dto.PersonaInfoParaControlDTO;
import py.com.alfa.escriba.persistence.dto.PersonasdocumentosDTO;
import py.com.alfa.escriba.persistence.dto.PersonasjuridicasinfoDTO;
import py.com.alfa.escriba.persistence.dto.PoderesDTO;
import py.com.alfa.escriba.persistence.dto.admin.DomicilioDTO;
import py.com.alfa.escriba.persistence.dto.admin.PersonaDTO;
import py.com.alfa.escriba.persistence.dto.admin.PersonaInfoDTO;
import py.com.alfa.escriba.persistence.dto.admin.TelefonoDTO;
import py.com.alfa.escriba.persistence.dto.query.PersonaQueryDTO;
import py.com.alfa.escriba.persistence.dto.referencia.TabRefDTO;
import py.com.alfa.escriba.util.Utils;
import py.com.alfa.escriba.web.interceptor.InvocationContext;
import py.com.alfa.escriba.web.services.AdminService;

@Transactional(readOnly = true)
public class AdminServiceImpl implements AdminService {

	private Logger log = LoggerFactory.getLogger(getClass());
	private AdminDAO adminDAO;
	private PersonasDAO personasDAO;
	private ReferenciaDAO referenciaDAO;
	private PaisDAO paisDAO;
	private PersonasjuridicasinfoDAO personasJuridicasInfoDAO;
	private PersonasdocumentosDAO personasDocumentosDAO;
	private EscribanosDAO escribanosDAO;
	private ComparecientesDAO comparecientesDAO;
	private PoderesDAO poderesDAO;
	
	public AdminServiceImpl() {}


	public AdminDAO getAdminDAO() {
		return adminDAO;
	}
	
	public void setPoderesDAO(PoderesDAO poderesDAO) {
		this.poderesDAO = poderesDAO;
	}
	public void setAdminDAO(AdminDAO adminDAO) {
		this.adminDAO = adminDAO;
	}
	
	public void setEscribanosDAO(EscribanosDAO escribanosDAO) {
		this.escribanosDAO = escribanosDAO;
	}


	public void setPersonasDAO(PersonasDAO personasDAO) {
		this.personasDAO = personasDAO;
	}
	
	public void setReferenciaDAO(ReferenciaDAO referenciaDAO) {
		this.referenciaDAO = referenciaDAO;
	}
	
	public void setPaisDAO(PaisDAO paisDAO){
		this.paisDAO = paisDAO;
	}	

	public void setPersonasJuridicasInfoDAO(
			PersonasjuridicasinfoDAO personasJuridicasInfoDAO) {
		this.personasJuridicasInfoDAO = personasJuridicasInfoDAO;
	}

	public void setComparecientesDAO(ComparecientesDAO comparecientesDAO) {
		this.comparecientesDAO = comparecientesDAO;
	}
	
	public void setPersonasDocumentosDAO(PersonasdocumentosDAO personasDocumentosDAO) {
		this.personasDocumentosDAO = personasDocumentosDAO;
	}



	@Override
	public PersonaDTO obtenerPersona(Long id) throws ServiceException {
		if ( id == null) {
		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		PersonaDTO dto = this.personasDAO.obtenerPersona(id);
		if ( dto == null ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", id);
		}		
		return dto;
	}

	@Override
	public PersonaInfoDTO obtenerPersonaInfo(Long id) throws ServiceException {
		if ( id == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		PersonaInfoDTO dto = this.personasDAO.obtenerPersonaInfo(id);
		if ( dto == null ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", id);
		}
		dto.setDomicilios(this.adminDAO.getDomiciliosByCliente(id));
		dto.setTelefonos(this.adminDAO.getTelefonosByCliente(id));
		dto.setDocumentos(this.personasDAO.documentosPersona(dto.getId()));
//		dto.setDocumentosJuridica(this.personasDAO.documentosPersonaJuridica(dto.getId()));
		dto.setTipoPersonaDTO(this.referenciaDAO.getTabRefById(dto.getTipoPersona()));
		dto.setSexoDTO(this.referenciaDAO.getTabRefById(dto.getSexo()));
		dto.setEstadoCivilDTO(this.referenciaDAO.getTabRefById(dto.getEstadoCivil()));
		dto.setPaisDTO(this.paisDAO.paisById(dto.getPais()));
		if(dto.getPersonaJuridica()!=null){
			List<ComparecientesDTO> comparecientes = new ArrayList<ComparecientesDTO>();
			comparecientes=comparecientesDAO.getComparecientesByIdPerJuridica(dto.getPersonaJuridica().getId());
			if(comparecientes!=null){
				for(ComparecientesDTO comp: comparecientes){
					comp.setRol(this.referenciaDAO.getTabRefById(comp.getIdRol()));
					comp.setEstadoCivilDTO(this.referenciaDAO.getTabRefById(comp.getIdEstadoCivil()));
					comp.setTipoDocumento(this.referenciaDAO.getTabRefById(comp.getIdTipoDocumento()));
					if(comp.getIdPoder()!=null){
						comp.setPoder(this.poderesDAO.getPoderesById(comp.getIdPoder()));
					}
				}
			}
			dto.getPersonaJuridica().setComparecientes(comparecientes);
			List<PoderesDTO> poderes= poderesDAO.getPoderesByIdPerJuridica(dto.getPersonaJuridica().getId());
			dto.getPersonaJuridica().setPoderes(poderes);
		}
		return dto;
	}
	
	@Override
	public PersonaInfoParaControlDTO getPersonaByPaisDocumento(PersonaQueryDTO values) throws ServiceException {
		System.out.println("PersonaQueryDTO"+values);
		if ( values == null ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", "parametros");
		}
		PersonaInfoParaControlDTO dto = null;
		dto = this.personasDAO.getPersonaByPaisDocumento(values);
		if(dto!=null && dto.getPersonaJuridica() != null){ 
			List<ComparecientesDTO> comparecientes = comparecientesDAO.getComparecientesByIdPerJuridica(dto.getPersonaJuridica().getId());
			if(comparecientes!=null){
				for(ComparecientesDTO comp: comparecientes){
					comp.setRol(this.referenciaDAO.getTabRefById(comp.getIdRol()));
					comp.setEstadoCivilDTO(this.referenciaDAO.getTabRefById(comp.getIdEstadoCivil()));
					comp.setTipoDocumento(this.referenciaDAO.getTabRefById(comp.getIdTipoDocumento()));
					if(comp.getIdPoder()!=null){
						comp.setPoder(this.poderesDAO.getPoderesById(comp.getIdPoder()));
					}
				}
				dto.setComparecientes(comparecientes);
			}
			
		}
		return dto;
	}
	
	@Override
	public List<PersonaDTO> obtenerPersonas(InvocationContext ic) throws ServiceException {
		List<PersonaDTO> res = this.personasDAO.obtenerPersonas(ic.getIdEscribano());
		return res;
	}
	
	@Override
	public List<PersonaInfoDTO> buscarPersonas(PersonaDTO dto,InvocationContext ic) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		dto.setIdEscribano(ic.getIdEscribano());
		if(dto.getNombresRazon()!=null ){
			dto.setNombresRazon("%"+dto.getNombresRazon()+"%");
		}
		if(dto.getApellidos()!=null){
			dto.setApellidos("%"+dto.getApellidos()+"%");
		}
		log.info("NombreRazon:"+dto.getNombresRazon()+"Apellido:"+dto.getApellidos());
		List<PersonaInfoDTO> res = this.personasDAO.buscarPersonas(dto);
		for(PersonaInfoDTO p:res){
			p.setTipoPersonaDTO(this.adminDAO.getTabRefsById(p.getTipoPersona()));
			p.setSexoDTO(this.adminDAO.getTabRefsById(p.getSexo()));
			p.setEstadoCivilDTO(this.adminDAO.getTabRefsById(p.getEstadoCivil()));
			p.setPaisDTO(this.paisDAO.paisById(p.getPais()));
		}
		return res;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public PersonaDTO crearPersona(PersonaDTO dto, InvocationContext ic) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		
		if ( dto.getFechaNacimientoCreacion() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.fecha.error");
		}
		Long trn = personasDAO.getTrnPersonas();
		dto.setTrn(trn+1L);
		TabRefDTO tipoPersona = adminDAO.getTabRefsById(dto.getTipoPersona());
		dto.setFechaCreacion(new Date(System.currentTimeMillis()));
		dto.setIdUsuario(ic.getIdUserPrincipal());
		this.personasDAO.crearPersona(dto);	
		PersonaDTO result = this.personasDAO.obtenerPersona(dto.getId());
		if(tipoPersona.getCodigo().equals("JUR")){
			if ( dto.getPersonaJuridica() == null) {
				throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
			}
			dto.getPersonaJuridica().setIdpersona(result.getId());
			this.personasJuridicasInfoDAO.createPersonaJuridica(dto.getPersonaJuridica());
			PersonasjuridicasinfoDTO resultado = this.personasJuridicasInfoDAO.getPersonaJuridicaById(dto.getPersonaJuridica().getId());
			//TODO agregar Legitimaciones
			if(dto.getPersonaJuridica().getPoderes()!=null){
				for(PoderesDTO pod: dto.getPersonaJuridica().getPoderes()){
					pod.setIdpersonajuridica(resultado.getId());
					pod.setFechacreacion(new Date(System.currentTimeMillis()));
					pod.setIdUsuario(ic.getIdUserPrincipal());
					log.info("id del poder1;"+pod.getId());
					Long idTempPoder=pod.getIdTemp();
					pod=this.createPoderes(pod);
					pod.setIdTemp(idTempPoder);
					log.info("id del poder2;"+pod.getId());
				}
			}
			if(dto.getPersonaJuridica().getComparecientes()!=null){
				for (ComparecientesDTO leg : dto.getPersonaJuridica().getComparecientes() ){
					leg.setIdpersonajuridica(resultado.getId());
					leg.setFechacreacion(new Date(System.currentTimeMillis()));
					leg.setIdUsuario(ic.getIdUserPrincipal());
					if(leg.getIdTempPoder()!=null){
						for(PoderesDTO pod: dto.getPersonaJuridica().getPoderes()){
							if(pod.getIdTemp().equals(leg.getIdTempPoder())){
								leg.setIdPoder(pod.getId());
								break;
							}
						}
					}
					this.createComparecientes(leg);	
				}
			}
			
			result.setPersonaJuridica(resultado);
		}
		return result;
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public PersonaDTO actualizarPersona(PersonaDTO dto, InvocationContext ic) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		if ( dto.getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		dto.setTrn(personasDAO.getTrnPersonas()+1L);
		dto.setFechaModificacion(new Date(System.currentTimeMillis()));
		dto.setIdUsuarioModificacion(ic.getIdUserPrincipal());
		int res = this.personasDAO.updPersona(dto);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", dto.getId());
		}
		PersonaDTO person = this.personasDAO.obtenerPersona(dto.getId());
		TabRefDTO tipoPersona = adminDAO.getTabRefsById(dto.getTipoPersona());
		log.info("tipoPersona:"+tipoPersona.getCodigo());
		if(tipoPersona.getCodigo().equals("JUR")){
			if ( dto.getPersonaJuridica() == null) {
				throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
			}
			dto.getPersonaJuridica().setIdpersona(dto.getId());
			int resp = this.personasJuridicasInfoDAO.updatePersonaJuridica(dto.getPersonaJuridica());
			if ( resp == 0 ) {
					throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", dto.getId());
			}
			//TODO falta actualizar legitimaciones
//			log.info("inicia borrar comparecientes");
//			resp = this.comparecientesDAO.deleteComparecientesByIdPerJuridica(dto.getPersonaJuridica().getId());
//			log.info("inicia borrar poderes");
//			resp=this.poderesDAO.deletePoderesByIdPerJuridica(dto.getPersonaJuridica().getId());
//			if ( resp == 0 ) {
//					throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", dto.getId());
//				}
			PersonasjuridicasinfoDTO resultado = this.personasJuridicasInfoDAO.getPersonaJuridicaById(dto.getPersonaJuridica().getId());
			log.info("trae datos de persona juridica actualizado");
			List<ComparecientesDTO> comparecientes= dto.getPersonaJuridica().getComparecientes();
			List<PoderesDTO> poderes=dto.getPersonaJuridica().getPoderes();
			log.info("comparecientes.size:"+comparecientes.size()+" poderes.size:"+poderes.size());
			if(poderes!=null){
				for(PoderesDTO pod: poderes){
					pod.setFechamodificacion(new Date(System.currentTimeMillis()));
					pod.setIdusuariomodificacion(ic.getIdUserPrincipal());
					if(pod.getId()==null){
						pod.setIdpersonajuridica(resultado.getId());
						if(pod.getFechacreacion()==null)
							pod.setFechacreacion(new Date(System.currentTimeMillis()));
						if(pod.getIdUsuario()==null)
							pod.setIdUsuario(ic.getIdUserPrincipal());
						log.info("id del poder1;"+pod.getId());
						Long idTempPoder=pod.getIdTemp();
						pod=this.createPoderes(pod);
						pod.setIdTemp(idTempPoder);
						log.info("id del poder2;"+pod.getId());
					}else{
						
						this.poderesDAO.updatePoderes(pod);
					}
					
				}
			}
			if(comparecientes!=null){
				for (ComparecientesDTO leg : comparecientes ){
					if(leg.getIdTempPoder()!=null){
						for(PoderesDTO pod: dto.getPersonaJuridica().getPoderes()){
							if(pod.getIdTemp().equals(leg.getIdTempPoder())){
								leg.setIdPoder(pod.getId());
								break;
							}
						}
					}
					leg.setFechamodificacion(new Date(System.currentTimeMillis()));
					leg.setIdusuariomodificacion(ic.getIdUserPrincipal());
					if(leg.getId()==null){
						leg.setIdpersonajuridica(resultado.getId());
						if(leg.getFechacreacion()==null)
							leg.setFechacreacion(new Date(System.currentTimeMillis()));
						if(leg.getIdUsuario()==null)
						leg.setIdUsuario(ic.getIdUserPrincipal());
						
						this.createComparecientes(leg);
						
					}else{
						this.comparecientesDAO.updateComparecientes(leg);
					}
						
				}
			}
			resultado.setComparecientes(comparecientes);
			person.setPersonaJuridica(resultado);
		}
		return person;
	}


//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public List<ClienteDTO> obtenerClientes() throws ServiceException {
//		List<ClienteDTO> res = this.adminDAO.getClientes();
//		return res;
//	}


//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public ClienteInfoDTO obtenerCliente(Long id) throws ServiceException {
//		if ( id == null) {
//		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		ClienteDTO dto = this.adminDAO.getClienteById(id);
//		if ( dto == null ) {
//			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.error", id);
//		}
//		ClienteInfoDTO res = new ClienteInfoDTO(dto);
//		res.setDomicilios(this.adminDAO.getDomiciliosByCliente(id));
//		//res.setEmpleos(this.adminDAO.getEmpleosByCliente(id));
//		res.setTelefonos(this.adminDAO.getTelefonosByCliente(id));
//		
//		return res;
//	}


//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public ClienteDTO actualizarCliente(ClienteDTO dto) throws ServiceException {
//		if ( dto == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		if ( dto.getId() == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		dto.setTrn(adminDAO.getTrnClientes()+1L);
//		int res = this.adminDAO.updCliente(dto);
//		if ( res == 0 ) {
//			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.error", dto.getId());
//		}		
//		return this.adminDAO.getClienteById(dto.getId());
//	}
//
//
//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public void eliminarCliente(Long id) throws ServiceException {
//		if ( id == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		this.adminDAO.delDomicilioByCliente(id);
//		this.adminDAO.delTelefonoByCliente(id);
//		//this.adminDAO.delTrabajoPersonalByCliente(id);
//		int res = this.adminDAO.delCliente(id);
//		if ( res == 0 ) {
//			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.error", id);
//		}
//	}
//
//
//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public ClienteDTO crearCliente(ClienteDTO dto) throws ServiceException {
//		if ( dto == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		Long trn = adminDAO.getTrnClientes();
//		dto.setTrn(trn+1L);
//		this.getAdminDAO().insCliente(dto);		
//		return this.adminDAO.getClienteById(dto.getId());
//	}
//
//
//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public void eliminarEmpleoCliente(IntercepcionLongDTO dto) throws ServiceException {
//		if ( dto == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.empleo.error");
//		}
//		if ( dto.getIdTab() == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		if ( dto.getIdTabR() == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.idEmpleo.error");
//		}
//		//int res = this.adminDAO.delTrabajoPersonal(dto);
//		int res = 1;
//		if ( res == 0 ) {
//			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.trabajo.error", dto.getIdTabR(), dto.getIdTab());
//		}		
//	}
//
//
//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
//	public void crearEmpleoCliente(IntercepcionLongDTO dto) throws ServiceException {
//		if ( dto == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.empleo.error");
//		}
//		if ( dto.getIdTab() == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.id.error");
//		}
//		if ( dto.getIdTabR() == null) {
//			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.idEmpleo.error");
//		}
//		//this.adminDAO.insTrabajoPersonal(dto);		
//	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void actualizarTelefono(TelefonoDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.telefono.error");
		}		
		if ( dto.getTipo() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.error");
		}
		int res = this.adminDAO.updTelefono(dto);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.telefono.error", dto.getTipo().getDescripcion());
		}			
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarTelefono(TelefonoDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.telefono.error");
		}		
		if ( dto.getTipo() == null || dto.getTipo().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.error");
		}
		//int res = this.adminDAO.delTelefono(dto);
		int res = 1;
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.telefono.error", dto.getTipo().getDescripcion());
		}	
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public TelefonoDTO crearTelefono(TelefonoDTO dto) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.telefono.error");
		}		
		if ( dto.getTipo() == null || dto.getTipo().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.error");
		}
		int res = this.adminDAO.insTelefono(dto);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.telefono.error", dto.getTipo().getDescripcion());
		}	
		return dto;
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DomicilioDTO actualizarDomicilio(DomicilioDTO dto) throws ServiceException {

		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.domicilio.error");
		}		
		if ( dto.getTipo() == null || dto.getTipo().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.domicilio.error");
		}
		if ( dto.getDepartamento() == null || dto.getDepartamento().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.departamento.domicilio.error");
		}
		if ( dto.getDistrito() == null || dto.getDistrito().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.distrito.domicilio.error");
		}
		
		dto.setTrn(dto.getTrn()+1L);
		int res = this.adminDAO.updDomicilio(dto);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.domicilio.error");
		}
		log.info("actualizo domicilio:"+dto.getId());
		return this.adminDAO.getDomicilio(dto.getId());
		
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public void eliminarDomicilio(Long id) throws ServiceException {
		if ( id == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.domicilio.error");
		}
		int res = this.adminDAO.delDomicilio(id);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.domicilio.error");
		}
		
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public DomicilioDTO crearDomicilio(DomicilioDTO dto) throws ServiceException {
		if ( dto == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.domicilio.error");
		}		
		if ( dto.getTipo() == null || dto.getTipo().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.domicilio.error");
		}
		if ( dto.getDepartamento() == null || dto.getDepartamento().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.departamento.domicilio.error");
		}
		if ( dto.getDistrito() == null || dto.getDistrito().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.distrito.domicilio.error");
		}
		Long trn = adminDAO.getTrnDomicilios();
		dto.setTrn(trn+1L);
		this.adminDAO.insDomicilio(dto);	
		return this.adminDAO.getDomicilio(dto.getId());		
	}


//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
//	public ClienteInfoDTO crearClienteInfo(ClienteInfoDTO dto) throws ServiceException {
//		try {
//	        ClienteDTO res = this.crearCliente(dto);
//	        if ( res == null) {
//	        	return null;
//	        }
//	        dto.setId(res.getId());
//	        dto.setTrn(res.getTrn());
//	        for (DomicilioDTO dom : dto.getDomicilios()) {
//	        	DomicilioDTO tmp = null;
//				//dom.setIdCliente(dto.getId());
//				tmp = this.crearDomicilio(dom);
//				if (tmp == null) {
//					return null;
//				}
//				dom.setId(tmp.getId());
//				dom.setTrn(tmp.getTrn());
//			}
//	        for (TelefonoDTO tel : dto.getTelefonos()) {
//			    //tel.setIdCliente(dto.getId());
//			    this.crearTelefono(tel);
//			}    
//		} catch (DuplicateKeyException e){
//			this.log.error(e.toString(), e);
//            throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.cliente.duplicate.key");
//        }        
//		return dto;
//	}
//
//
//	@Override
//	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
//	public void actualizarClienteInfo(ClienteInfoDTO dto) throws ServiceException {
//		try {
//			this.actualizarCliente(dto);
//			
//	        for (Long ids : dto.getEliminados()) {
//				this.getAdminDAO().delDomicilio(ids);
//			}
//			for (DomicilioDTO dom : dto.getDomicilios()) {
//				this.actualizarDomicilio(dom);
//			}
//	        this.getAdminDAO().delTelefonoByCliente(dto.getId());
//	        for (TelefonoDTO tel : dto.getTelefonos()) {
//			    this.crearTelefono(tel);
//			}
//	        
//		} catch (DuplicateKeyException e){
//			this.log.error(e.toString(), e);
//            throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.cliente.duplicate.key");
//        }    	
//	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public PersonaInfoDTO crearPersonaInfo(PersonaInfoDTO dto, InvocationContext ic) throws ServiceException {
		
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}

		TabRefDTO tipoPersona = adminDAO.getTabRefsById(dto.getTipoPersona());	
		log.info("tipoPersona:"+tipoPersona.getDescripcion());
		try {
			PersonaDTO per = this.crearPersona(dto, ic);
	        if ( per == null) {
	        	return null;
	        }
	        
	        for (DomicilioDTO dom : dto.getDomicilios()) {
	        	DomicilioDTO tmp = null;
				dom.setPersona(per);
				tmp = this.crearDomicilio(dom);
				if (tmp == null) {
					return null;
				}
				dom.setId(tmp.getId());
				dom.setTrn(tmp.getTrn());
			}
	        if(dto.getTelefonos()==null || dto.getTelefonos().size()==0 ){
	        	throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.not.telefono");
	        }
	        for (TelefonoDTO tel : dto.getTelefonos()) {
			    tel.setPersona(per);
			    tel.setIsClient(dto.isCliente() ? 1 : 0);
			    this.crearTelefono(tel);
			}
	        if(dto.getDocumentos()==null || dto.getDocumentos().size()==0 ){
	        	throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.not.documento");
	        }
	        Boolean tieneCi=false;
	        Boolean tienePas=false;
	        
	        for (PersonasdocumentosDTO doc : dto.getDocumentos()) {
				if(doc.getId() == null){
					doc.setIdpersona(per.getId());
					doc.setPersona(per);
					this.crearDocumento(doc);
					TabRefDTO tipoDocumento = this.adminDAO.getTabRefsById(doc.getIdtipodocumento());
					if(tipoDocumento.getCodigo().equals("CI")){
						tieneCi=true;
					}
					if(tipoDocumento.getCodigo().equals("PAS")){
						tienePas=true;					
					}
					if(!tipoDocumento.getCodigo().equals("RUC") && tipoPersona.getCodigo().equals("JUR")){
						throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.juridica.documento");
					}
				}else{
					this.actualizarDocumento(doc);
				}
			}
	        if(tipoPersona.getCodigo().equals("FIS") && !tieneCi && !tienePas){
	        	throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.ci.pas.error");	
	        }
	        
		} catch (DuplicateKeyException e){
			this.log.error(e.toString(), e);
            throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.duplicate.key");
        }        
		return dto;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public void actualizarPersonaInfo(PersonaInfoDTO dto, InvocationContext ic) throws ServiceException {
		
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		TabRefDTO tipoPersona = adminDAO.getTabRefsById(dto.getTipoPersona());
		try {
			PersonaDTO per = this.actualizarPersona(dto, ic);
			if(dto.getEliminadosComparecientes()!=null){
				for(Long id:dto.getEliminadosComparecientes()){
					ComparecientesDTO co=new ComparecientesDTO();
					co.setId(id);
					this.comparecientesDAO.deleteComparecientes(co);
				}
			}
	        for (Long ids : dto.getEliminadosDomicilios()) {
				this.getAdminDAO().delDomicilio(ids);
			}
			for (DomicilioDTO dom : dto.getDomicilios()) {
				if(dom.getId() == null){
					dom.setPersona(per);
					this.crearDomicilio(dom);
				}else{
					this.actualizarDomicilio(dom);
				}
			}
			
			if(dto.getTelefonos()!=null || dto.getTelefonos().size()>0 ){
				this.getAdminDAO().delTelefonoByCliente(dto.getId());
		        for (TelefonoDTO tel : dto.getTelefonos()) {
		        	tel.setPersona(per);
				    this.crearTelefono(tel);
				}
		        
		        for (Long ids : dto.getEliminadosDocumentos()) {
					this.getAdminDAO().delDocumento(ids);
				}
	        }
	        
	        if(dto.getDocumentos()==null || dto.getDocumentos().size()==0 ){
	        	throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.not.documento");
	        }
	        Boolean tieneCi=false;
	        Boolean tienePas=false;
	        
			for (PersonasdocumentosDTO doc : dto.getDocumentos()) {
				TabRefDTO tipoDocumento = this.adminDAO.getTabRefsById(doc.getIdtipodocumento());
				if(tipoDocumento.getCodigo().equals("CI")){
					tieneCi=true;
				}
				if(tipoDocumento.getCodigo().equals("PAS")){
					tienePas=true;					
				}
				if(!tipoDocumento.getCodigo().equals("RUC") && tipoPersona.getCodigo().equals("JUR")){
					throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.juridica.documento");
				}
				if(doc.getId() == null){
					doc.setIdpersona(per.getId());
					doc.setPersona(per);
					this.crearDocumento(doc);
				}else{
					this.actualizarDocumento(doc);
				}
			}
	        if(tipoPersona.getCodigo().equals("FIS") && !tieneCi && !tienePas){
	        	throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.ci.pas.error");	
	        }
	        
		} catch (DuplicateKeyException e){
			this.log.error(e.toString(), e);
            throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "admin.persona.duplicate.key");
        }    	
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public PersonasdocumentosDTO crearDocumento(PersonasdocumentosDTO dto) throws ServiceException {
		if ( dto == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.documento.error");
		}		
		if ( dto.getTipoDocumento() == null || dto.getTipoDocumento().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.documento.error");
		}
		if ( dto.getNrodocumento() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.nro.documento.error");
		}
		this.personasDocumentosDAO.createPersonasdocumentos(dto);	
		return this.personasDocumentosDAO.getPersonasdocumentosById(dto.getId());
	}
	
	@Override
	@Transactional(readOnly = false, propagation = Propagation.SUPPORTS, rollbackFor=ServiceException.class)
	public PersonasdocumentosDTO actualizarDocumento(PersonasdocumentosDTO dto) throws ServiceException {
		if ( dto == null ) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.documento.error");
		}		
		if ( dto.getTipoDocumento() == null || dto.getTipoDocumento().getId() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.tipo.documento.error");
		}
		if ( dto.getNrodocumento()== null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.cliente.not.nro.documento.error");
		}
		int res = this.personasDocumentosDAO.updatePersonasdocumentos(dto);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.documento.error");
		}
		return this.personasDocumentosDAO.getPersonasdocumentosById(dto.getId());
	}


	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public void eliminarPersonaInfo(Long id) throws ServiceException {
		if(id==null){
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		PersonaInfoDTO person = this.personasDAO.obtenerPersonaInfo(id);
		int res;
		TabRefDTO tipoPersona = this.adminDAO.getTabRefsById(person.getTipoPersona());
		if(tipoPersona.getCodigo().equals("JUR")){
			res=this.comparecientesDAO.deleteComparecientesByIdPerJuridica(person.getPersonaJuridica().getId());
			res=this.poderesDAO.deletePoderesByIdPerJuridica(person.getPersonaJuridica().getId());
			res=this.personasJuridicasInfoDAO.deletePersonaJuridicaByIdPersona(id);
//			if ( res == 0 ) {
//				throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.id.error");
//			}
		}		
		try{
			res = this.adminDAO.delTelefonoByCliente(id);
//			if ( res == 0 ) {
//				throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.telefono.error");
//			}
			res=this.adminDAO.delDomicilioByCliente(id);
//			if ( res == 0 ) {
//				throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.domicilio.error");
//			}
			res=this.adminDAO.delDocumentoByCliente(id);
//			if ( res == 0 ) {
//				throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.cliente.not.exist.documento.error");
//			}
			res=this.personasDAO.delPersona(id);
//			if ( res == 0 ) {
//				throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.id.error");
//			}
		}catch(Exception e){
			log.error(e.getMessage(),e);
			throw new ServiceException(ErrorCode.DATA_INTEGRITY_VIOLATION,"admin.persona.fk");
		}
		
		
	}
	
	@Override
	public EscribanosDTO obtenerEscribano(Long id) throws ServiceException {
		if ( id == null) {
		   throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.escribano.not.id.error");
		}
		EscribanosDTO escribano = escribanosDAO.getEscribanosById(id);
		if ( escribano == null ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.escribano.not.exist.error", id);
		}
		escribano.setPersona(obtenerPersonaInfo(escribano.getIdpersona()));
		return escribano;
	}

	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public EscribanosDTO crearEscribano(EscribanosDTO dto, InvocationContext ic) throws ServiceException {
		if ( dto == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		if ( dto.getPersona() == null) {
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.id.error");
		}
		TabRefDTO tipoPersona = adminDAO.getTabRefsById(dto.getPersona().getTipoPersona());
		if(tipoPersona.getCodigo().equals("JUR")){
				throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.fisica.escribano.error");
		}
		if(dto.getRegitronro()==null){
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.nroReg.escribano.error");
		}
		
		Boolean tieneCi=false;        
        for (PersonasdocumentosDTO doc : dto.getPersona().getDocumentos()) {
			if(doc.getId() == null){
				TabRefDTO tipoDocumento = this.adminDAO.getTabRefsById(doc.getIdtipodocumento());
				if(tipoDocumento.getCodigo().equals("CI")){
					tieneCi=true;
				}
			}
        }
        if(!tieneCi){
			throw new ServiceException(ErrorCode.PARAMETER_ERROR,"admin.persona.not.ci.escribano.error");
		}
        
        PersonaInfoDTO persona= crearPersonaInfo(dto.getPersona(), ic);
        dto.setIdpersona(persona.getId());
        dto.setFechacreacion(new Date(System.currentTimeMillis()));
		dto.setIdusuario(ic.getIdUserPrincipal());
        this.escribanosDAO.createEscribanos(dto);
        EscribanosDTO escribano = escribanosDAO.getEscribanosById(dto.getId());
        persona.setIdEscribano(escribano.getId());
        persona.setFechaModificacion(new Date(System.currentTimeMillis()));
        persona.setIdUsuarioModificacion(ic.getIdUserPrincipal());
        int res = this.personasDAO.updPersona(persona);
		if ( res == 0 ) {
			throw new ServiceException(ErrorCode.NO_DATA_FOUND,"admin.persona.not.exist.error", dto.getId());
		}
		return escribano;
	}
	
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public ComparecientesDTO createComparecientes(ComparecientesDTO dto) throws ServiceException {
		    if (dto == null)
		      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		    try {

		      Utils.validarDTO(dto);

		      comparecientesDAO.createComparecientes(dto);
		    }
		    catch (DuplicateKeyException e){
		      throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "legitimaciones.duplicate.key");
		    }

		    return dto;
	}

	@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor=ServiceException.class)
	public PoderesDTO createPoderes(PoderesDTO dto) throws ServiceException {
		    if (dto == null)
		      throw new ServiceException(ErrorCode.PARAMETER_ERROR,"parameter.error.null","dto");

		    try {

		      Utils.validarDTO(dto);

		      poderesDAO.createPoderes(dto);
		    }
		    catch (DuplicateKeyException e){
		      throw new ServiceException(ErrorCode.DUPLICATE_KEY_EXCEPTION, "poderes.duplicate.key");
		    }

		    return dto;
	}
	@Override
	public List<EscribanosDTO> obtenerEscribanos() throws ServiceException {
		List<EscribanosDTO> res = this.escribanosDAO.listEscribanos();
		for(EscribanosDTO e:res){
			PersonaInfoDTO p = new PersonaInfoDTO();
			p=this.obtenerPersonaInfo(e.getIdpersona());
			e.setPersona(p);
		}
		return res;
	}


}
